"""
KidsBuddy 1.0 硬件状态机
负责管理台灯硬件的状态转换和Flow控制逻辑
"""

import asyncio
import time
from enum import Enum
from typing import Dict, Optional, Callable, Any
from loguru import logger
from dataclasses import dataclass


class HardwareState(Enum):
    """硬件状态枚举"""
    IDLE = "idle"                    # 空闲状态
    INITIALIZING = "initializing"    # 初始化状态
    MONITORING = "monitoring"        # 监督状态
    ADJUSTING = "adjusting"         # 调整状态
    ALERTING = "alerting"           # 警告状态
    ERROR = "error"                 # 错误状态
    MAINTENANCE = "maintenance"      # 维护状态


class CommandPriority(Enum):
    """指令优先级枚举"""
    EMERGENCY = 1      # 紧急指令（安全相关）
    HIGH = 2          # 高优先级（用户交互）
    NORMAL = 3        # 普通优先级（监督任务）
    LOW = 4           # 低优先级（数据同步）
    BACKGROUND = 5    # 后台任务（日志清理）


@dataclass
class HardwareCommand:
    """硬件指令数据结构"""
    command_id: str
    command_type: str
    priority: CommandPriority
    payload: Dict[str, Any]
    timestamp: float
    callback: Optional[Callable] = None


class HardwareCommandQueue:
    """硬件指令队列管理器"""
    
    def __init__(self):
        self.queues = {
            CommandPriority.EMERGENCY: [],
            CommandPriority.HIGH: [],
            CommandPriority.NORMAL: [],
            CommandPriority.LOW: [],
            CommandPriority.BACKGROUND: []
        }
        self._lock = asyncio.Lock()
    
    async def add_command(self, command: HardwareCommand):
        """添加指令到队列"""
        async with self._lock:
            self.queues[command.priority].append(command)
            logger.debug(f"Added command {command.command_id} with priority {command.priority}")
    
    async def get_next_command(self) -> Optional[HardwareCommand]:
        """获取下一个待执行指令"""
        async with self._lock:
            for priority in CommandPriority:
                if self.queues[priority]:
                    command = self.queues[priority].pop(0)
                    logger.debug(f"Retrieved command {command.command_id}")
                    return command
            return None
    
    def get_queue_status(self) -> Dict[CommandPriority, int]:
        """获取队列状态"""
        return {priority: len(queue) for priority, queue in self.queues.items()}


class HardwareStateMachine:
    """硬件状态机"""
    
    def __init__(self):
        self.current_state = HardwareState.IDLE
        self.previous_state = None
        self.state_start_time = time.time()
        self.command_queue = HardwareCommandQueue()
        self.state_handlers = self._init_state_handlers()
        self.transition_rules = self._init_transition_rules()
        self._running = False
        
    def _init_state_handlers(self) -> Dict[HardwareState, Callable]:
        """初始化状态处理器"""
        return {
            HardwareState.IDLE: self._handle_idle_state,
            HardwareState.INITIALIZING: self._handle_initializing_state,
            HardwareState.MONITORING: self._handle_monitoring_state,
            HardwareState.ADJUSTING: self._handle_adjusting_state,
            HardwareState.ALERTING: self._handle_alerting_state,
            HardwareState.ERROR: self._handle_error_state,
            HardwareState.MAINTENANCE: self._handle_maintenance_state,
        }
    
    def _init_transition_rules(self) -> Dict[HardwareState, list]:
        """初始化状态转换规则"""
        return {
            HardwareState.IDLE: [
                HardwareState.INITIALIZING,
                HardwareState.MAINTENANCE,
                HardwareState.ERROR
            ],
            HardwareState.INITIALIZING: [
                HardwareState.MONITORING,
                HardwareState.ERROR,
                HardwareState.IDLE
            ],
            HardwareState.MONITORING: [
                HardwareState.ADJUSTING,
                HardwareState.ALERTING,
                HardwareState.IDLE,
                HardwareState.ERROR
            ],
            HardwareState.ADJUSTING: [
                HardwareState.MONITORING,
                HardwareState.ERROR,
                HardwareState.IDLE
            ],
            HardwareState.ALERTING: [
                HardwareState.MONITORING,
                HardwareState.ERROR,
                HardwareState.IDLE
            ],
            HardwareState.ERROR: [
                HardwareState.MAINTENANCE,
                HardwareState.IDLE
            ],
            HardwareState.MAINTENANCE: [
                HardwareState.IDLE,
                HardwareState.ERROR
            ]
        }
    
    async def transition_to(self, new_state: HardwareState, reason: str = "") -> bool:
        """状态转换"""
        if new_state not in self.transition_rules[self.current_state]:
            logger.warning(f"Invalid transition from {self.current_state} to {new_state}")
            return False
        
        logger.info(f"State transition: {self.current_state} -> {new_state}. Reason: {reason}")
        
        self.previous_state = self.current_state
        self.current_state = new_state
        self.state_start_time = time.time()
        
        return True
    
    async def start(self):
        """启动状态机"""
        self._running = True
        logger.info("Hardware state machine started")
        
        while self._running:
            try:
                # 处理当前状态
                handler = self.state_handlers.get(self.current_state)
                if handler:
                    await handler()
                
                # 处理指令队列
                await self._process_command_queue()
                
                # 短暂休眠避免CPU占用过高
                await asyncio.sleep(0.01)
                
            except Exception as e:
                logger.error(f"State machine error: {e}")
                await self.transition_to(HardwareState.ERROR, f"Exception: {e}")
    
    async def stop(self):
        """停止状态机"""
        self._running = False
        logger.info("Hardware state machine stopped")
    
    async def _process_command_queue(self):
        """处理指令队列"""
        command = await self.command_queue.get_next_command()
        if command:
            await self._execute_command(command)
    
    async def _execute_command(self, command: HardwareCommand):
        """执行指令"""
        try:
            logger.debug(f"Executing command: {command.command_type}")
            
            # 根据指令类型执行相应操作
            if command.command_type == "start_monitoring":
                await self.transition_to(HardwareState.MONITORING, "Start monitoring command")
            elif command.command_type == "stop_monitoring":
                await self.transition_to(HardwareState.IDLE, "Stop monitoring command")
            elif command.command_type == "trigger_alert":
                await self.transition_to(HardwareState.ALERTING, "Alert triggered")
            elif command.command_type == "adjust_environment":
                await self.transition_to(HardwareState.ADJUSTING, "Environment adjustment")
            
            # 执行回调
            if command.callback:
                await command.callback(command)
                
        except Exception as e:
            logger.error(f"Command execution error: {e}")
    
    # 状态处理器方法
    async def _handle_idle_state(self):
        """处理空闲状态"""
        pass
    
    async def _handle_initializing_state(self):
        """处理初始化状态"""
        # 模拟初始化过程
        await asyncio.sleep(0.1)
    
    async def _handle_monitoring_state(self):
        """处理监督状态"""
        # 在监督状态下，状态机主要协调各个监督循环
        pass
    
    async def _handle_adjusting_state(self):
        """处理调整状态"""
        # 模拟调整过程
        await asyncio.sleep(0.1)
        await self.transition_to(HardwareState.MONITORING, "Adjustment completed")
    
    async def _handle_alerting_state(self):
        """处理警告状态"""
        # 模拟警告处理
        await asyncio.sleep(0.1)
        await self.transition_to(HardwareState.MONITORING, "Alert handled")
    
    async def _handle_error_state(self):
        """处理错误状态"""
        # 错误恢复逻辑
        await asyncio.sleep(1.0)
        await self.transition_to(HardwareState.IDLE, "Error recovery")
    
    async def _handle_maintenance_state(self):
        """处理维护状态"""
        # 维护逻辑
        await asyncio.sleep(0.1)
    
    def get_state_info(self) -> Dict[str, Any]:
        """获取状态信息"""
        return {
            "current_state": self.current_state.value,
            "previous_state": self.previous_state.value if self.previous_state else None,
            "state_duration": time.time() - self.state_start_time,
            "queue_status": self.command_queue.get_queue_status()
        }
